<template>
  <el-dialog
    v-model="visible"
    width="1200px"
    :close-on-click-modal="false"
    class="unified-dialog job-discovery-dialog"
    @close="handleClose"
  >
    <template #header>
      <div class="dialog-header">
        <div class="header-icon header-icon-success">
          <el-icon><Search /></el-icon>
        </div>
        <div class="header-content">
          <h3>发现未注册作业</h3>
          <p>从 Flink 集群自动发现未注册的作业，选择并注册到监控系统</p>
        </div>
      </div>
    </template>

    <div class="discovery-content" v-loading="loading">
      <!-- Flink 环境选择 -->
      <div class="env-selector">
        <el-form label-width="100px">
          <el-form-item label="Flink环境">
            <div class="env-select-row">
              <el-select
                v-model="selectedFlinkEnv"
                placeholder="选择Flink环境进行扫描"
                clearable
                filterable
                style="flex: 1"
                popper-class="batch-dialog-select-popper"
                :teleported="true"
                @change="handleEnvChange"
              >
                <el-option
                  v-for="env in environmentOptions"
                  :key="env.value"
                  :label="`${env.label} (${env.host}:${env.port})`"
                  :value="env.value"
                />
              </el-select>
              <el-button 
                type="primary" 
                @click="handleDiscover" 
                :loading="loading"
                :disabled="!selectedFlinkEnv"
              >
                <el-icon><Search /></el-icon>
                开始扫描
              </el-button>
            </div>
          </el-form-item>
        </el-form>
      </div>

      <!-- 统计信息 -->
      <div class="stats-bar" v-if="!loading && discoveryData">
        <div class="stat-item">
          <el-icon><Folder /></el-icon>
          <span>Flink 总作业：<strong>{{ discoveryData.total_flink_jobs }}</strong></span>
        </div>
        <div class="stat-item">
          <el-icon><Check /></el-icon>
          <span>已注册：<strong>{{ discoveryData.registered_jobs_count }}</strong></span>
        </div>
        <div class="stat-item success">
          <el-icon><Star /></el-icon>
          <span>未注册：<strong>{{ discoveryData.unregistered_count }}</strong></span>
        </div>
      </div>

      <!-- 初始状态 -->
      <el-empty
        v-if="!loading && !discoveryData"
        description="请选择 Flink 环境并点击【开始扫描】来发现未注册的作业"
      />

      <!-- 无未注册作业状态 -->
      <div v-if="!loading && discoveryData && unregisteredJobs.length === 0" class="success-result">
        <el-result
          icon="success"
          title="扫描完成"
          sub-title="未发现新作业，所有 Flink 作业已注册"
        >
          <template #icon>
            <div class="success-icon">
              <el-icon><CircleCheck /></el-icon>
            </div>
          </template>
          <template #extra>
            <el-button type="primary" @click="handleDiscover" :loading="loading">
              <el-icon><Refresh /></el-icon>
              重新扫描
            </el-button>
          </template>
        </el-result>
      </div>

      <!-- 作业列表 -->
      <div v-if="!loading && unregisteredJobs.length > 0" class="jobs-list">
        <!-- JAR基路径配置 -->
        <div class="jar-path-config">
          <el-form label-width="100px" size="small">
            <el-form-item label="JAR基路径">
              <el-input
                v-model="jarBasePath"
                placeholder="/opt/flink/userjars/flink-web-upload"
                style="max-width: 500px"
              >
                <template #prepend>
                  <el-icon><FolderOpened /></el-icon>
                </template>
              </el-input>
              <div class="form-tip">
                <el-icon><InfoFilled /></el-icon>
                注册作业时将使用此路径拼接 JAR 包名生成完整路径
              </div>
            </el-form-item>
          </el-form>
        </div>
        
        <div class="list-header">
          <el-checkbox
            v-model="selectAll"
            @change="handleSelectAll"
            :indeterminate="indeterminate"
          >
            全选 ({{ selectedJobs.length }}/{{ unregisteredJobs.length }})
          </el-checkbox>
          <el-button
            type="primary"
            size="small"
            :disabled="selectedJobs.length === 0"
            @click="handleBatchRegister"
          >
            <el-icon><Check /></el-icon>
            批量注册 ({{ selectedJobs.length }})
          </el-button>
        </div>

        <div class="job-cards">
          <div
            v-for="job in sortedUnregisteredJobs"
            :key="job.job_id"
            class="job-card"
            :class="{
              selected: isJobSelected(job.job_id),
              'warning-card': hasMissingFields(job)
            }"
            @click="toggleJobSelection(job.job_id)"
          >
            <div class="card-header">
              <el-checkbox
                :model-value="isJobSelected(job.job_id)"
                @click.stop
                @change="toggleJobSelection(job.job_id)"
              />
              <div class="job-title">
                <el-icon><Cpu /></el-icon>
                <span>{{ job.job_name }}</span>
              </div>
              <el-tag :type="getStateType(job.state)" size="small">
                {{ job.state }}
              </el-tag>
              <!-- 警告标签：缺少必填字段 -->
              <el-tag v-if="hasMissingFields(job)" type="warning" size="small" effect="plain">
                <el-icon style="vertical-align: middle; margin-right: 4px;"><Warning /></el-icon>
                需手动填写
              </el-tag>
            </div>

            <div class="card-body">
              <div class="job-info-grid">
                <div class="info-item">
                  <span class="label">作业 ID：</span>
                  <span class="value">{{ job.job_id }}</span>
                </div>
                <div class="info-item" v-if="job.start_time">
                  <span class="label">启动时间：</span>
                  <span class="value">{{ job.start_time }}</span>
                </div>
                <div class="info-item" v-if="job.tasks_total">
                  <span class="label">任务数：</span>
                  <span class="value">{{ job.tasks_total }}</span>
                </div>
                <div class="info-item" v-if="job.parallelism">
                  <span class="label">并行度：</span>
                  <span class="value">{{ job.parallelism }}</span>
                </div>
              </div>

              <!-- 编辑表单 -->
              <div class="edit-form" v-if="isJobSelected(job.job_id)" @click.stop>
                <el-form :model="getJobForm(job.job_id)" label-width="100px" size="small">
                  <el-row :gutter="12">
                    <el-col :span="12">
                      <el-form-item label="作业名称" required>
                        <el-input
                          v-model="getJobForm(job.job_id).job_name"
                          placeholder="请输入作业名称"
                        />
                      </el-form-item>
                    </el-col>
                    <el-col :span="12">
                      <el-form-item label="作业描述">
                        <el-input
                          v-model="getJobForm(job.job_id).job_description"
                          placeholder="请输入作业描述"
                        />
                      </el-form-item>
                    </el-col>
                  </el-row>
                  <el-row :gutter="12">
                    <el-col :span="12">
                      <el-form-item label="JAR 包名" required>
                        <el-input
                          v-model="getJobForm(job.job_id).jar_name"
                          placeholder="例如：example-job.jar"
                          :class="{ 'input-warning': !getJobForm(job.job_id).jar_name }"
                        >
                          <template #suffix v-if="getJobForm(job.job_id).jar_name">
                            <el-icon color="#67c23a"><CircleCheck /></el-icon>
                          </template>
                          <template #suffix v-else>
                            <el-icon color="#e6a23c"><Warning /></el-icon>
                          </template>
                        </el-input>
                        <div v-if="!getJobForm(job.job_id).jar_name" class="field-warning-hint">
                          <el-icon><Warning /></el-icon>
                          <span>未匹配到 JAR 包，请手动填写</span>
                        </div>
                      </el-form-item>
                    </el-col>
                    <el-col :span="12">
                      <el-form-item label="入口类" required>
                        <el-input
                          v-model="getJobForm(job.job_id).entry_class"
                          placeholder="例如：com.example.MainJob"
                          :class="{ 'input-warning': !getJobForm(job.job_id).entry_class }"
                        >
                          <template #suffix v-if="getJobForm(job.job_id).entry_class">
                            <el-icon color="#67c23a"><CircleCheck /></el-icon>
                          </template>
                          <template #suffix v-else>
                            <el-icon color="#e6a23c"><Warning /></el-icon>
                          </template>
                        </el-input>
                        <div v-if="!getJobForm(job.job_id).entry_class" class="field-warning-hint">
                          <el-icon><Warning /></el-icon>
                          <span>未匹配到入口类，请手动填写</span>
                        </div>
                      </el-form-item>
                    </el-col>
                  </el-row>
                  <el-form-item label="程序参数">
                    <el-input
                      v-model="getJobForm(job.job_id).program_args"
                      type="textarea"
                      :rows="2"
                      placeholder="例如：--param1 value1 --param2 value2"
                    />
                    <div class="form-hint" v-if="getJobForm(job.job_id).jar_name || getJobForm(job.job_id).entry_class">
                      <el-icon><InfoFilled /></el-icon>
                      <span>已根据作业名称自动填充建议值，请检查并修改</span>
                    </div>
                  </el-form-item>
                  <el-row :gutter="12">
                    <el-col :span="8">
                      <el-form-item label="自动恢复">
                        <el-switch v-model="getJobForm(job.job_id).auto_recovery" />
                      </el-form-item>
                    </el-col>
                    <el-col :span="8">
                      <el-form-item label="最大重试">
                        <el-input-number
                          v-model="getJobForm(job.job_id).max_recovery_attempts"
                          :min="1"
                          :max="10"
                        />
                      </el-form-item>
                    </el-col>
                    <el-col :span="8">
                      <el-form-item label="Savepoint间隔(h)">
                        <el-input-number
                          v-model="getJobForm(job.job_id).savepoint_interval"
                          :min="1"
                          :max="168"
                        />
                      </el-form-item>
                    </el-col>
                  </el-row>
                </el-form>
              </div>
            </div>

            <div class="card-footer" v-if="isJobSelected(job.job_id)" @click.stop>
              <el-button
                type="primary"
                size="small"
                @click="handleRegisterSingle(job.job_id)"
                :loading="registeringJobs.includes(job.job_id)"
              >
                <el-icon><Check /></el-icon>
                注册此作业
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <template #footer>
      <el-button @click="handleClose">关闭</el-button>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useFlinkEnvStore } from '@/stores/flinkEnv'
import { useAppStore } from '@/stores/app'
import api from '@/utils/api'
import { componentLogger } from '@/utils/logger'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  }
})

const emit = defineEmits(['update:modelValue', 'success'])

const flinkEnvStore = useFlinkEnvStore()
const appStore = useAppStore()

const visible = computed({
  get: () => props.modelValue,
  set: (val) => emit('update:modelValue', val)
})

const loading = ref(false)
const discoveryData = ref(null)
const unregisteredJobs = ref([])
const selectedJobs = ref([])
const registeringJobs = ref([])
const jobForms = ref({})
const selectedFlinkEnv = ref('')
const jarBasePath = ref('/opt/flink/userjars/flink-web-upload')

// 环境选项
const environmentOptions = computed(() => flinkEnvStore.getEnvironmentOptions())

// 全选状态
const selectAll = ref(false)
const indeterminate = computed(() => {
  return selectedJobs.value.length > 0 && selectedJobs.value.length < unregisteredJobs.value.length
})

// 获取状态类型
const getStateType = (state) => {
  const typeMap = {
    'RUNNING': 'success',
    'FINISHED': 'info',
    'FAILED': 'danger',
    'CANCELED': 'warning',
    'CANCELING': 'warning'
  }
  return typeMap[state] || 'info'
}

// 判断作业是否被选中
const isJobSelected = (jobId) => {
  return selectedJobs.value.includes(jobId)
}

// 判断作业是否缺少必填字段（JAR 包名或入口类）
const hasMissingFields = (job) => {
  return !job.suggested_jar_name || !job.suggested_entry_class
}

// 对作业列表排序：缺少必填字段的排在前面
const sortedUnregisteredJobs = computed(() => {
  if (!unregisteredJobs.value || unregisteredJobs.value.length === 0) {
    return []
  }
  
  // 复制数组以避免直接修改原数组
  const jobs = [...unregisteredJobs.value]
  
  // 排序：缺少字段的在前，完整的在后
  return jobs.sort((a, b) => {
    const aMissing = hasMissingFields(a)
    const bMissing = hasMissingFields(b)
    
    // 如果 a 缺少字段，b 不缺少，a 排在前面（返回 -1）
    if (aMissing && !bMissing) return -1
    // 如果 a 不缺少字段，b 缺少，b 排在前面（返回 1）
    if (!aMissing && bMissing) return 1
    // 如果都缺少或都不缺少，保持原顺序
    return 0
  })
})

// 切换作业选择
const toggleJobSelection = (jobId) => {
  const index = selectedJobs.value.indexOf(jobId)
  if (index > -1) {
    selectedJobs.value.splice(index, 1)
  } else {
    selectedJobs.value.push(jobId)
    // 初始化表单数据（使用后端的智能匹配结果）
    if (!jobForms.value[jobId]) {
      const job = unregisteredJobs.value.find(j => j.job_id === jobId)
      jobForms.value[jobId] = {
        job_id: job.job_id,
        job_name: job.job_name,
        job_description: job.suggested_description || '',
        // 直接使用后端的智能匹配结果
        jar_name: job.suggested_jar_name || '',
        entry_class: job.suggested_entry_class || '',
        program_args: job.suggested_program_args || '',
        auto_recovery: true,
        max_recovery_attempts: 3,
        savepoint_interval: 24
      }
    }
  }
}

// 全选/取消全选
const handleSelectAll = (val) => {
  if (val) {
    selectedJobs.value = unregisteredJobs.value.map(job => job.job_id)
    // 初始化所有表单（使用后端的智能匹配结果）
    unregisteredJobs.value.forEach(job => {
      if (!jobForms.value[job.job_id]) {
        jobForms.value[job.job_id] = {
          job_id: job.job_id,
          job_name: job.job_name,
          job_description: job.suggested_description || '',
          // 直接使用后端的智能匹配结果
          jar_name: job.suggested_jar_name || '',
          entry_class: job.suggested_entry_class || '',
          program_args: job.suggested_program_args || '',
          auto_recovery: true,
          max_recovery_attempts: 3,
          savepoint_interval: 24
        }
      }
    })
  } else {
    selectedJobs.value = []
  }
}

// 获取作业表单
const getJobForm = (jobId) => {
  return jobForms.value[jobId] || {}
}

// 环境切换处理
const handleEnvChange = (env) => {
  // 环境选择改变，不做其他操作
}

// 发现未注册作业
const handleDiscover = async () => {
  loading.value = true
  try {
    // selectedFlinkEnv.value 已经是完整的 URL，直接传递
    // API 拦截器会自动添加 flink_env 参数
    
    // 临时设置环境（通过 params 传递，而不是通过 appStore）
    const params = {}
    if (selectedFlinkEnv.value) {
      params.flink_env = selectedFlinkEnv.value
    }
    
    // API 路径不需要 /api 前缀，因为 axios 实例已经设置了 baseURL: '/api'
    const response = await api.get('/jobs/discover-unregistered', { params })
    if (response.data.success) {
      discoveryData.value = response.data.data
      unregisteredJobs.value = response.data.data.unregistered_jobs
      selectedJobs.value = []
      jobForms.value = {}
      
      // 只在发现未注册作业时显示提示
      if (response.data.data.unregistered_count > 0) {
        ElMessage.success(`发现 ${response.data.data.unregistered_count} 个未注册作业`)
      }
    } else {
      ElMessage.error(response.data.error || '发现作业失败')
    }
  } catch (error) {
    componentLogger.error('发现作业失败', error)
    ElMessage.error('发现作业失败：' + (error.response?.data?.error || error.message))
  } finally {
    loading.value = false
  }
}

// 注册单个作业
const handleRegisterSingle = async (jobId) => {
  const form = jobForms.value[jobId]
  
  // 验证必填字段
  if (!form.job_name || !form.jar_name || !form.entry_class) {
    ElMessage.warning('请填写作业名称、JAR包名和入口类')
    return
  }
  
  registeringJobs.value.push(jobId)
  
  try {
    const response = await api.post('/jobs/register', {
      job_id: form.job_id,
      job_name: form.job_name,
      job_description: form.job_description,
      jar_name: form.jar_name,
      jar_base_path: jarBasePath.value,  // 添加 JAR 基路径
      entry_class: form.entry_class,
      program_args: form.program_args,
      auto_recovery: form.auto_recovery ? 1 : 0,
      max_recovery_attempts: form.max_recovery_attempts,
      savepoint_interval: form.savepoint_interval
    })
    
    if (response.data.success) {
      ElMessage.success(`作业 "${form.job_name}" 注册成功`)
      // 从列表中移除已注册的作业
      unregisteredJobs.value = unregisteredJobs.value.filter(job => job.job_id !== jobId)
      selectedJobs.value = selectedJobs.value.filter(id => id !== jobId)
      delete jobForms.value[jobId]
      
      // 如果没有更多未注册作业，触发成功事件
      if (unregisteredJobs.value.length === 0) {
        emit('success')
        handleClose()
      }
    } else {
      ElMessage.error(response.data.error || '注册作业失败')
    }
  } catch (error) {
    componentLogger.error('注册作业失败', error)
    ElMessage.error('注册作业失败：' + (error.response?.data?.error || error.message))
  } finally {
    registeringJobs.value = registeringJobs.value.filter(id => id !== jobId)
  }
}

// 批量注册
const handleBatchRegister = async () => {
  // 验证所有选中作业的必填字段
  const invalidJobs = selectedJobs.value.filter(jobId => {
    const form = jobForms.value[jobId]
    return !form || !form.job_name || !form.jar_name || !form.entry_class
  })
  
  if (invalidJobs.length > 0) {
    ElMessage.warning('请为所有选中作业填写完整信息（作业名称、JAR包名、入口类）')
    return
  }
  
  let successCount = 0
  let failCount = 0
  
  for (const jobId of selectedJobs.value) {
    try {
      registeringJobs.value.push(jobId)
      const form = jobForms.value[jobId]
      
      const response = await api.post('/jobs/register', {
        job_id: form.job_id,
        job_name: form.job_name,
        job_description: form.job_description,
        jar_name: form.jar_name,
        jar_base_path: jarBasePath.value,  // 添加 JAR 基路径
        entry_class: form.entry_class,
        program_args: form.program_args,
        auto_recovery: form.auto_recovery ? 1 : 0,
        max_recovery_attempts: form.max_recovery_attempts,
        savepoint_interval: form.savepoint_interval
      })
      
      if (response.data.success) {
        successCount++
        // 从列表中移除
        unregisteredJobs.value = unregisteredJobs.value.filter(job => job.job_id !== jobId)
        delete jobForms.value[jobId]
      } else {
        failCount++
      }
    } catch (error) {
      failCount++
      componentLogger.error(`注册作业 ${jobId} 失败`, error)
    } finally {
      registeringJobs.value = registeringJobs.value.filter(id => id !== jobId)
    }
  }
  
  // 清空选中列表
  selectedJobs.value = []
  
  // 显示结果
  if (successCount > 0) {
    ElMessage.success(`成功注册 ${successCount} 个作业${failCount > 0 ? `，${failCount} 个失败` : ''}`)
  }
  if (failCount > 0 && successCount === 0) {
    ElMessage.error(`批量注册失败`)
  }
  
  // 如果全部注册成功
  if (unregisteredJobs.value.length === 0) {
    emit('success')
    handleClose()
  }
}

const handleClose = () => {
  visible.value = false
  selectedJobs.value = []
  jobForms.value = {}
}

// 监听对话框打开，初始化状态
watch(visible, async (newVal) => {
  if (newVal) {
    // 重置状态
    discoveryData.value = null
    unregisteredJobs.value = []
    selectedJobs.value = []
    jobForms.value = {}
    
    // 加载环境列表（如果还没有加载）
    if (flinkEnvStore.flinkEnvironments.length === 0) {
      await flinkEnvStore.fetchFlinkEnvironments()
    }
    
    // 设置默认环境（如果有的话）
    if (!selectedFlinkEnv.value && environmentOptions.value.length > 0) {
      // 使用 URL 作为 value，而不是环境名称
      selectedFlinkEnv.value = environmentOptions.value[0].value
    }
  }
})
</script>

<style scoped>
/* 对话框已使用统一样式系统 */

.discovery-content {
  min-height: 300px;
}

.env-selector {
  padding: 16px;
  background: linear-gradient(135deg, #f5f7fa 0%, #e9ecef 100%);
  border-radius: 8px;
  margin-bottom: 20px;
}

.env-selector .el-form-item {
  margin-bottom: 0;
}

.env-select-row {
  display: flex;
  gap: 12px;
  align-items: center;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 8px;
  display: block;
}

.success-result {
  padding: 40px 20px;
}

.success-icon {
  width: 80px;
  height: 80px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
  border-radius: 50%;
  color: white;
  font-size: 48px;
  box-shadow: 0 4px 20px rgba(103, 194, 58, 0.3);
  animation: successPulse 2s ease-in-out infinite;
}

@keyframes successPulse {
  0%, 100% {
    transform: scale(1);
    box-shadow: 0 4px 20px rgba(103, 194, 58, 0.3);
  }
  50% {
    transform: scale(1.05);
    box-shadow: 0 6px 24px rgba(103, 194, 58, 0.4);
  }
}

.stats-bar {
  display: flex;
  gap: 20px;
  padding: 16px;
  background: linear-gradient(135deg, #f5f7fa 0%, #e9ecef 100%);
  border-radius: 8px;
  margin-bottom: 20px;
}

.stat-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 16px;
  background: white;
  border-radius: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
}

.stat-item.success {
  color: #67c23a;
  font-weight: 600;
}

.stat-item strong {
  font-size: 18px;
  color: #409eff;
}

/* JAR基路径配置区域 */
.jar-path-config {
  padding: 16px;
  background: linear-gradient(135deg, #f0f9ff 0%, #e0f2fe 100%);
  border-radius: 8px;
  margin-bottom: 16px;
  border: 1px solid #bae6fd;
}

.jar-path-config .el-form-item {
  margin-bottom: 0;
}

.jar-path-config .form-tip {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 8px;
  font-size: 12px;
  color: #0369a1;
}

.jar-path-config .form-tip .el-icon {
  font-size: 14px;
  color: #0284c7;
}

.jobs-list {
  margin-top: 20px;
}

.list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  background: #f5f7fa;
  border-radius: 8px;
  margin-bottom: 16px;
}

.job-cards {
  display: grid;
  gap: 16px;
  max-height: 500px;
  overflow-y: auto;
}

.job-card {
  border: 2px solid #e4e7ed;
  border-radius: 8px;
  padding: 16px;
  background: white;
  transition: all 0.3s ease;
  cursor: pointer;
}

.job-card:hover {
  border-color: #409eff;
  box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
}

.job-card.selected {
  border-color: #409eff;
  background: #ecf5ff;
}

/* 警告卡片样式：缺少必填字段 */
.job-card.warning-card {
  border-color: #e6a23c;
  background: linear-gradient(135deg, #fef8f0 0%, #ffffff 100%);
  position: relative;
}

.job-card.warning-card::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 4px;
  background: linear-gradient(180deg, #e6a23c 0%, #f39c12 100%);
  border-radius: 8px 0 0 8px;
}

.job-card.warning-card:hover {
  border-color: #e6a23c;
  box-shadow: 0 4px 12px rgba(230, 162, 60, 0.2);
}

.job-card.warning-card.selected {
  border-color: #e6a23c;
  background: linear-gradient(135deg, #fef0e6 0%, #fef8f0 100%);
}

.card-header {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-bottom: 12px;
}

.job-title {
  display: flex;
  align-items: center;
  gap: 8px;
  flex: 1;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.card-body {
  padding-top: 12px;
  border-top: 1px solid #e4e7ed;
}

.job-info-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: 12px;
}

.info-item {
  font-size: 13px;
}

.info-item .label {
  color: #909399;
}

.info-item .value {
  color: #606266;
  font-weight: 500;
}

.edit-form {
  margin-top: 16px;
  padding: 16px;
  background: #f9fafc;
  border-radius: 6px;
}

.card-footer {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid #e4e7ed;
  display: flex;
  justify-content: flex-end;
}

.form-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  padding: 8px 12px;
  background: #f0f9ff;
  border-left: 3px solid #409eff;
  border-radius: 4px;
  font-size: 13px;
  color: #606266;
}

.form-hint .el-icon {
  color: #409eff;
  font-size: 16px;
}

/* 警告输入框样式 */
.input-warning :deep(.el-input__wrapper) {
  border-color: #e6a23c;
  background: #fef8f0;
  box-shadow: 0 0 0 1px #e6a23c inset;
}

.input-warning :deep(.el-input__wrapper):hover {
  border-color: #e6a23c;
  box-shadow: 0 0 0 1px #e6a23c inset;
}

.input-warning :deep(.el-input__wrapper.is-focus) {
  border-color: #e6a23c;
  box-shadow: 0 0 0 1px #e6a23c inset;
}

/* 字段警告提示 */
.field-warning-hint {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 6px 10px;
  background: #fef0e6;
  border-left: 3px solid #e6a23c;
  border-radius: 4px;
  font-size: 12px;
  color: #e6a23c;
  animation: shake 0.5s ease-in-out;
}

.field-warning-hint .el-icon {
  color: #e6a23c;
  font-size: 14px;
}

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-4px); }
  75% { transform: translateX(4px); }
}
</style>

